package org.yocastlong.mybatisplus.db.encryption;

import cn.hutool.crypto.Mode;
import cn.hutool.crypto.Padding;
import cn.hutool.crypto.SecureUtil;
import cn.hutool.crypto.symmetric.SM4;
import org.springframework.util.Base64Utils;

import javax.crypto.SecretKey;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

/**
 * @author 朱海龙
 * 2025/6/7 8:38
 */
public class Sm4Manager {

    private final static Map<Sm4CacheKey, SM4> sm4Map = new HashMap<>();

    private Sm4Manager() {
        throw new AssertionError("can not instantiate me");
    }

    public static SM4 getSm4Instance(Sm4CacheKey sm4Key) {
        SM4 sm4 = sm4Map.getOrDefault(sm4Key, null);
        if (Objects.isNull(sm4)) {
            sm4 = generateSm4(sm4Key);
        }
        return sm4;
    }

    private static SM4 generateSm4(Sm4CacheKey sm4Key) {
        final String iv = sm4Key.getIv();
        final String key = sm4Key.getKey();
        final Mode mode = sm4Key.getMode();
        final Padding padding = sm4Key.getPadding();
        final SM4 sm4 = new SM4(mode, padding, Base64Utils.decodeFromString(key));
        sm4.setIv(Base64Utils.decodeFromString(iv));
        return sm4;
    }

    private static Sm4CacheKey generateSm4Key() {
        Sm4CacheKey sm4Key = new Sm4CacheKey();
        SecretKey secretKey = SecureUtil.generateKey("sm4");
        byte[] encoded = secretKey.getEncoded();
        String key = Base64Utils.encodeToString(encoded);
        sm4Key.setKey(key);
        System.out.println("key : " + key);
        secretKey = SecureUtil.generateKey("sm4");
        encoded = secretKey.getEncoded();
        String iv = Base64Utils.encodeToString(encoded);
        sm4Key.setIv(iv);
        System.out.println("iv : " + iv);
        return sm4Key;
    }

    public static void main(String[] args) {
        generateSm4Key();

        String key = "IJ60jHoqrYw9KHUUy6oFrw==";
        String iv = "cKdUUk5MagMuRTlp+jxMNQ==";
        SM4 sm4 = new SM4(Mode.CBC, Padding.PKCS5Padding,Base64Utils.decodeFromString(key));
        sm4.setIv(Base64Utils.decodeFromString(iv));
        String s1 = sm4.encryptBase64("朱海龙");
        System.out.println(s1);
        System.out.println(sm4.decryptStr(s1));
    }


}
